<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style media="screen">
        body {background: #000;}
        #svg {background: #fff;}
    </style>
</head>
<body>
    <svg id="svg" width="800" height="800">
    </svg>
    <script>
        //数据
        let data = [{name:'数据1',num:500}, {name:'数据2',num:200}, {name:'数据3',num:300}, {name:'数据4',num:50}];
        let svg = document.getElementById('svg');
        let sw = svg.getAttribute('width');
        let sh = svg.getAttribute('height');
        let r = 150;
        let max = 0;
        let s = 0;
        let cx = 400,cy = 400;
        data.forEach((item)=>{max += item.num});
        data.forEach((item,index)=>{
            let a = item.num / max * 360;
            let color = `rgb(${Math.floor(Math.random()*256)}, ${Math.floor(Math.random()*256)}, ${Math.floor(Math.random()*256)})`;
            setPie(s, s + a, item, color);
            setData((s + s + a) / 2, item, color);
            s += a;
        });
        function d2a(n) {
            return n * Math.PI / 180;
        }

        function getPoint(ang) {
            return {
                x: cx + Math.sin(d2a(ang)) * r,
                y: cy + Math.cos(d2a(ang)) * r
            }
        }

        function setPie(start, end, item, color) {
            let path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path.style.fill = color;
            svg.appendChild(path);
            let {x: x1, y: y1} = getPoint(start);
            let {x: x2, y: y2} = getPoint(end);
            if (end - start > 180) {
                path.setAttribute('d', `M ${cx} ${cy} L ${x1} ${y1} A ${r} ${r} 0 1 0 ${x2} ${y2} Z`);

            } else {
                path.setAttribute('d', `M ${cx} ${cy} L ${x1} ${y1} A ${r} ${r} 0 0 0 ${x2} ${y2} Z`);

            }
        }

        function getLine(x, y) {
            return (y - cy) / (x - cx);
        }

        function setData(arg, item, color) {
            let len = 30, lang = 20, font = 20;
            let x1,x2,y1,txtX,txtY;
            let txtW = item.name.length * font;
            let {x: x, y: y} = getPoint(arg);

            let path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            let txt = document.createElementNS('http://www.w3.org/2000/svg', 'text');
            txt.innerHTML = item.name;
            path.style.fill = 'none';
            path.style.stroke = color;
            txt.style.fill = color;
            txt.style.fontSize = font + 'px';
            svg.appendChild(path);
            svg.appendChild(txt);

            if (x <= cx) {     // 文字在饼图左边
                x1 = x - len;
                txtX = x1 - txtW - lang;
                x2 = x1 - lang;
            } else {     // 文字在饼图右边
                x1 = x + len;
                txtX = x1 + font + lang / 2;
                x2 = x1 + lang;
            }

            if (y <= cy) {     // 文字在饼图上边
                y1 = y - len;
                txtY = y1 + font / 2;
            } else {      // 文字在饼图下边
                y1 = y + len;
                txtY = y1 + font / 2;
            }
            path.setAttribute('d', `M ${x} ${y} L ${x1} ${y1} L ${x2} ${y1}`);
            txt.setAttribute('x', txtX);
            txt.setAttribute('y', txtY);
            /*
            if (arg > 180) {
                if (arg > 270) {
                    yl = yl * ((y1 - cy) / (cx - x1));
                    path.setAttribute('d', `M ${x1} ${y1} L ${x1 - xl} ${y1 + yl} L ${x1 - xl - 30} ${y1 + yl}`);
                    txt.setAttribute('x', x1 - xl - 30 - txtW);
                    txt.setAttribute('y', y1 + yl);
                } else {
                    xl = xl * ((cx - x1) / (cy - y1));
                    console.log(xl)
                    path.setAttribute('d', `M ${x1} ${y1} L ${x1 - xl} ${y1 - yl} L ${x1 - xl - 30} ${y1 - yl}`);
                    txt.setAttribute('x', x1 - xl - 30 - txtW);
                    txt.setAttribute('y', y1 - yl);
                }
            } else {
                if (arg > 90) {
                    xl = xl * ((x1 - cx) / (cy - y1));
                    path.setAttribute('d', `M ${x1} ${y1} L ${x1 + xl} ${y1 - yl} L ${x1 + xl + 30} ${y1 - yl}`);
                    txt.setAttribute('x', x1 + xl + 30 + 10);
                    txt.setAttribute('y', y1 - yl);
                } else {
                    yl = yl * ((y1 - cy) / (x1 - cx));
                    path.setAttribute('d', `M ${x1} ${y1} L ${x1 + xl} ${y1 + yl} L ${x1 + xl + 30} ${y1 + yl}`);
                    txt.setAttribute('x', x1 + xl + 30 + 10);
                    txt.setAttribute('y', y1 + yl);
                }
            }
            */
        }

    </script>
</body>
</html>
